﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Web.Configuration;
using System.Net;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Net.Mime;

namespace AP.Framework.Utilities.Utilities.Email
{
    public class EmailMessage
    {
        #region EmailMessage 成员
        /// <summary>
        /// 发件人
        /// </summary>
        public string Sender { get; set; }
        /// <summary>
        /// 发送地址
        /// </summary>
        public string ToAddress { get; set; }
        /// <summary>
        /// 抄送地址
        /// </summary>
        public string CcAddress { get; set; }
        /// <summary>
        /// 密送地址
        /// </summary>
        public string BccAddress { get; set; }
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 正文
        /// </summary>
        public string Body { get; set; }
        /// <summary>
        /// 签名
        /// </summary>
        public string Signature { get; set; }
        #endregion
    }

    /// <summary>
    /// 邮件发送类
    /// </summary>
    public class EmailUtility
    {
        private StringDictionary errorCodes = new StringDictionary();
        private Hashtable EmbedList = new Hashtable(); //widened scope for MatchEvaluator
        /// <summary>
        /// author:andy-peng
        /// CreateDate:2011-05-06
        /// 发送邮件
        /// </summary>
        /// <param name="message"></param>
        public static void SendMail(EmailMessage message)
        {
            var exName = string.Empty;
            var exMsg = string.Empty;
            try
            {
                MailAddress from = new MailAddress(message.Sender);
                string[] ToAdd = EmailAddressSplit(message.ToAddress, ";");
                string[] BccAdd = null;
                string[] CcAdd = null;
                MailMessage sendmail = new MailMessage();
                sendmail.From = from;
                //ToAddress
                if (ToAdd != null)
                {
                    foreach (string address in ToAdd)
                    {
                        if (!string.IsNullOrWhiteSpace(address))
                        {
                            if (EmailAddressValidation(address))
                            {
                                sendmail.To.Add(address);
                            }

                        }

                    }
                }

                //BccAddress
                if (!string.IsNullOrWhiteSpace(message.BccAddress))
                {
                    BccAdd = EmailAddressSplit(message.BccAddress, ";");
                    if (BccAdd != null)
                    {
                        foreach (string address in BccAdd)
                        {
                            if (!string.IsNullOrWhiteSpace(address))
                                sendmail.Bcc.Add(address);
                        }
                    }
                }
                //CcAddress
                if (!string.IsNullOrWhiteSpace(message.CcAddress))
                {
                    CcAdd = EmailAddressSplit(message.CcAddress, ";");
                    if (CcAdd != null)
                    {
                        foreach (string address in CcAdd)
                        {
                            if (!string.IsNullOrWhiteSpace(address))
                                sendmail.CC.Add(address);
                        }
                    }
                }
                sendmail.Subject = message.Title;
                sendmail.IsBodyHtml = true;
                sendmail.BodyEncoding = Encoding.UTF8;
                EmailUtility Utility = new EmailUtility();
                AlternateView htmlView = null;
                LinkedResource lrImage = null;
                Utility.ImageMatching(message.Body, ref htmlView, lrImage);
                sendmail.AlternateViews.Add(htmlView);
                SmtpClient smtp = new SmtpClient();
                smtp.Send(sendmail);
            }
            catch (SmtpException ex)
            {
                exName = "smtpException";
                exMsg = ex.ToString();
                throw new Exception(exMsg);

            }
            catch (FormatException ex)
            {
                exName = "FormatException";
                exMsg = ex.ToString();
                throw new Exception(exMsg);
            }
            catch (Exception ex)
            {
                exName = ex.Source;
                exMsg = ex.ToString();
                throw new Exception(exMsg);
            }
        }

        /// <summary>
        /// author:andy
        /// CreateDate:2011-05-17
        /// 字符串截取,返回指定的值
        /// </summary>
        /// <param name="strings"></param>
        /// <param name="index"></param>
        /// <param name="Separ"></param>
        /// <returns></returns>

        public static string StringSplit(string strings, int index, string Separ)
        {
            try
            {
                string[] s = strings.Split(char.Parse(Separ));
                return s[index];
            }
            catch (Exception)
            {
                return string.Empty;
            }

        }
        /// <summary>
        /// author:andy
        /// CreateDate:2011-05-17
        /// 邮件地址分割
        /// </summary>
        /// <param name="strings"></param>
        /// <param name="Separ"></param>
        /// <returns></returns>
        public static string[] EmailAddressSplit(string strings, string Separ)
        {
            string[] s = null;
            if (!string.IsNullOrWhiteSpace(strings))
            {
                s = strings.Split(char.Parse(Separ));
            }
            return s;
        }

        /// <summary>
        /// Author:Andy-Peng
        /// CreateDate:2012-06-26
        /// 邮箱地址验证
        /// </summary>
        /// <param name="EmailBody"></param>
        /// <returns></returns>

        public static bool EmailAddressValidation(string EmailAddress)
        {
            string Pattern = @"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}";
            Regex reg = new Regex(Pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            Match m = reg.Match(EmailAddress);
            if (m.Success)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Author:Andy-Peng
        /// CreateDate:2011-06-28
        /// 用正则表达式匹配Img,并以附件的形式发送
        /// </summary>
        /// <param name="EmailBody">邮件内容</param>
        /// <param name="htmlView">AlternateView</param>
        /// <param name="lrImage">LinkedResource</param>
        /// <returns></returns>
        public string ImageMatching(string EmailBody, ref AlternateView htmlView, LinkedResource lrImage)
        {
            Regex imgRE;
            MatchCollection imgMatches;
            string imgMatchExpression = "(?:img[^>]+src\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))|url\\(['\"](?<1>[^'\"]*)['\"]\\))";
            imgRE = new Regex(imgMatchExpression, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            imgMatches = imgRE.Matches(EmailBody);
            foreach (Match m in imgMatches)
            {
                if (!EmbedList.ContainsKey(m.Groups[1].Value))
                {
                    EmbedList.Add(m.Groups[1].Value, Guid.NewGuid());//将contentId使用GUID的格式，避免多张图片出现重复
                }
            }
            EmailBody = imgRE.Replace(EmailBody, new MatchEvaluator(ImgReplace));
            htmlView = AlternateView.CreateAlternateViewFromString(EmailBody, Encoding.UTF8, MediaTypeNames.Text.Html);
            string contentType;
            string contentId;
            string baseContentType;
            string baseDataValue;
            Byte[] bytes;
            Stream Streams;
            ArrayList embeddees = new ArrayList(EmbedList.Keys);
            foreach (string embeddee in embeddees)
            {
                baseContentType = StringSplit(embeddee, 0, ";");
                baseDataValue = StringSplit(embeddee, 1, ";");
                contentType = StringSplit(baseContentType, 1, ":");
                contentId = EmbedList[embeddee].ToString();
                bytes = Convert.FromBase64String(StringSplit(baseDataValue, 1, ","));
                Streams = new MemoryStream(bytes);
                try
                {
                    lrImage = new LinkedResource(Streams, contentType);//以流的形式增加附件的资源文件
                }
                catch (Exception)
                {
                    lrImage = new LinkedResource(embeddee);//如果出现异常，说明图片格式不一致
                }
              
                lrImage.ContentId = contentId;
                htmlView.LinkedResources.Add(lrImage);
            }
            return EmailBody;
        }
        /// <summary>
        /// Author:Andy-Peng
        /// CreateDate:2011-06-28
        /// 匹配并替换Img的Src属性,如:<img src="cid:4849e549-c837-46e0-8dfb-39c898681e15" />
        /// </summary>
        /// <returns></returns>
        private string ImgReplace(Match m)
        {
            string replaceThis = m.Groups[1].Value;
            string withThis = string.Format("cid:{0}", EmbedList[replaceThis]);
            return m.Value.Replace(replaceThis, withThis);
        }

    }

}
